<template>
  <div>
    <div id="darag" style="height: 100%">
      <!-- 组件库 -->
      <section class="left">
        <!--标题-->
        <h4>组件库</h4>
        <ul @dragstart="dragStart" @dragend="dragEnd">
          <!-- 添加自定义属性 data-type -->
          <li
            v-for="(val, key, index) in typeList"
            draggable
            :data-type="key"
            :key="index + 1"
          >
            <span :class="val.icon"></span>
            <p>{{ val.name }}</p>
          </li>
        </ul>
      </section>
      <!-- 展示区域 -->
      <section class="main" ref="main">
        <div class="top-nav" @click="selectType(0)">
          <img src="../../src/assets/images/topNavBlack.png" />
          <span class="tit">{{ info.title }}</span>
        </div>
        <div
          class="view-content"
          @drop="drog"
          @dragover="dragOver"
          :style="{ backgroundColor: info.backgroundColor }"
        >
          <Draggable v-model="view" draggable=".item" chosenClass="chosen">
            <template v-for="(item, index) in view">
              <div
                v-if="index > 0"
                :data-index="index"
                :key="index"
                class="item"
                @click="selectType(index)"
              >
                <!-- waiting -->
                <template v-if="item.status && item.status == 2">
                  <div class="wait">组件放置区域</div>
                </template>
                <template v-else>
                  <component
                    :is="typeList[item.type]['com']"
                    :data="item"
                    :className="className[item.tabType]"
                  ></component>
                </template>
                <i @click="deleteItem($event, index)" class="el-icon-error"></i>
              </div>
            </template>
          </Draggable>
        </div>
        <div><el-button @click="submit">导出</el-button></div>
      </section>
      <!-- 描述信息 -->
      <section class="right">
        <!-- 动态修改内容区域的值 -->
        <Index :data="props" v-if="isRight"></Index>
      </section>
    </div>

    <div>{{ computdata }}</div>
  </div>
</template>

<script>
import Draggable from "vuedraggable";
// 文本
import h_Text from "../components/main/text/text.vue";
// 图片
import h_Image from "../components/main/image/image.vue";
// 搜索
import h_search from "../components/main/search/search.vue";
// 公告
import h_notice from "../components/main/notice/notice.vue";
// 视频
import h_video from "../components/main/video/video.vue";
// 轮播图
import h_swiper from "../components/main/swiper/swiper.vue";
// 商品列表
import h_product from "../components/main/product/product.vue";
// 分割线
import h_divider from "../components/main/divider/divider.vue";
// 商店介绍
import h_shop from "../components/main/shop/shop.vue";
// 进入店铺
import h_store from "../components/main/store/store.vue";
// 内容卡片
import h_card from "../components/main/card/card.vue";
// 导航
import h_menu from "../components/main/menu/menu.vue";
// 导航广告
import h_menuad from "../components/main/menuad/menuad.vue";

import Index from "../components/Edit/index.vue";
export default {
  components: {
    Draggable,
    h_Text: h_Text,
    h_Image: h_Image,
    Index: Index,
    h_search: h_search,
    h_notice: h_notice,
    h_video: h_video,
    h_swiper: h_swiper,
    h_product: h_product,
    h_divider: h_divider,
    h_shop: h_shop,
    h_store: h_store,
    h_card,
    h_menu,
    h_menuad,
  },
  data() {
    return {
      label: "测试组件",
      // 左侧组件库数据
      typeList: {
        // 存放每个组件的数据结构
        text: {
          name: "文本",
          icon: "el-icon-picture",
          com: h_Text,
        },
        images: {
          name: "图片",
          icon: "el-icon-picture",
          com: h_Image,
        },
        search: {
          name: "搜索",
          icon: "el-icon-search",
          com: h_search,
        },
        notice: {
          name: "公告",
          icon: "el-icon-s-promotion",
          com: h_notice,
        },
        video: {
          name: "视频",
          icon: "el-icon-video-play",
          com: h_video,
        },
        swiper: {
          name: "轮播图",
          icon: "el-icon-turn-off",
          com: h_swiper,
        },
        product: {
          name: "商品列表",
          icon: "el-icon-sell",
          com: h_product,
        },
        divider: {
          name: "分割线",
          icon: "el-icon-crop",
          com: h_divider,
        },
        shop: {
          name: "店铺介绍",
          icon: "el-icon-crop",
          com: h_shop,
        },
        store: {
          name: "进入店铺",
          icon: "el-icon-crop",
          com: h_store,
        },
        card: {
          name: "内容卡片",
          icon: "el-icon-crop",
          com: h_card,
        },
        menu: {
          name: "导航",
          icon: "el-icon-help",
          com: h_menu,
        },
        menuad: {
          name: "图文广告",
          icon: "el-icon-help",
          com: h_menuad,
        },
      },
      view: [
        {
          type: "info",
          title: "页面标题123",
        },
      ],
      title: "页面标题",
      type: "",
      index: null, // 当前组件的索引
      isPush: false, // 是否已添加组件

      props: {}, // 传值
      isRight: false,

      className: {
        1: "one",
        2: "two",
        3: "three",
      },
    };
  },

  mounted() {},
  computed: {
    info() {
      return this.view[0];
    },
  },
  methods: {
    // 提交
    submit() {
      this.computdata = JSON.stringify(this.view);
      console.log();
      // JSON 转换会丢失 formData
      const form = JSON.parse(JSON.stringify(this.view));

      if (form.length == 1) {
        this.$message.error("请添加模块！");
        return;
      }

      for (let i of form) {
        if (i.data && i.data.length == 0) {
          this.$message.error("请填写完整信息！");
          return;
        }
        if (i.type === "product") {
          i.data = i.data.map((val) => val.productId).join(",");
        }
      }

      this.$message.success(
        "数据提交成功，请按F12打开控制台查看待提交数据集合！"
      );
      console.log(form); // 提交的数据，根据接口形式修改
      return;

      // 上传图片，修改数据字段（兼容接口
      const uploadPromise = {};
      for (let i = 0; i < this.view.length; i++) {
        if (["images", "banner"].includes(this.view[i].type)) {
          uploadPromise[i] = [];
          let list = this.view[i]["data"];
          list.forEach((item, index) => {
            uploadPromise[i].push(
              new Promise((resolve, reject) => {
                const link = item.link;
                const name = item.name;
                imageUpload(item.form)
                  .then((res) => {
                    // 上传图片接口
                    form[i]["data"][index] = {
                      url: res.data.url,
                      link,
                      name,
                    };
                    resolve(res);
                  })
                  .catch((err) => {
                    reject(err);
                  });
              })
            );
          });
        }
      }

      let [len, count] = [Object.keys(uploadPromise).length, 0];
      if (len) {
        for (let i in uploadPromise) {
          Promise.all(uploadPromise[i])
            .then((res) => {
              count++;
              if (count === len) {
                // 提交数据
              }
            })
            .catch((err) => {
              this.$message.error(err);
            });
        }
      } else {
        // 提交数据
      }
    },
    // 切换视图组件
    selectType(index) {
      console.log(this.props, "this.props");
      this.isRight = false;
      this.props = this.view[index];
      this.$nextTick(() => (this.isRight = true));
    },
    deleteItem(e, index) {
      e.preventDefault();
      e.stopPropagation();
      this.view.splice(index, 1);
      this.isRight = false;
      this.props = {};
    },
    // 拖拽类型
    dragStart(e) {
      this.type = e.target.dataset.type;
    },
    // 结束拖拽
    dragEnd(e) {
      this.$delete(this.view[this.index], "status");
      this.isPush = false;
      this.type = null;
    },
    // 已放置到指定位置
    drog(e) {
      if (!this.type) {
        // 内容拖拽
        return;
      }
      e.preventDefault();
      e.stopPropagation();
      this.dragEnd();
    },
    // 移动中
    dragOver(e) {
      if (!this.type) {
        // 内容拖拽
        return;
      }
      e.preventDefault();
      e.stopPropagation();

      let className = e.target.className;
      let name = className !== "view-content" ? "item" : "view-content";

      const defaultData = {
        type: this.type, // 组件类型
        status: 2, // 默认状态
        data: [], // 数据
        options: {}, // 选项操作
      };

      if (name == "view-content") {
        if (!this.isPush) {
          this.index = this.view.length;
          this.isPush = true;
          this.view.push(defaultData);
        }
      } else if (name == "item") {
        let target = e.target;
        let [y, h, curIndex] = [
          e.offsetY,
          target.offsetHeight,
          target.dataset.index,
        ];
        let direction = y < h / 2;

        if (!this.isPush) {
          // Push to Top or Bottom
          if (direction) {
            if (curIndex == 0) {
              this.view.unshift(defaultData);
            } else {
              this.view.splice(curIndex, 0, defaultData);
            }
          } else {
            curIndex = +curIndex + 1;
            this.view.splice(curIndex, 0, defaultData);
          }
        } else {
          // Moving
          if (direction) {
            var i = curIndex == 0 ? 0 : curIndex - 1;
            var result = this.view[i]["status"] == 2;
          } else {
            var i = +curIndex + 1;
            var result = this.view.length > i && this.view[i]["status"] == 2;
          }

          if (result) return;

          const temp = this.view.splice(this.index, 1);
          this.view.splice(curIndex, 0, temp[0]);
        }
        this.index = curIndex;
        this.isPush = true;
      }
    },
  },
};
</script>

<style lang="less" scoped>
#darag {
  display: flex;
  justify-content: space-between;
}
.left,
.right {
  background: #fafaf5;
  h4 {
    text-align: center;
    margin: 20px;
  }
  width: 440px;
  background: #fff;
}
.left {
  ul {
    margin: 0;
    padding: 0;
    li {
      width: 80px;
      height: 80px;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
      cursor: default;
      list-style: none;
      font-size: 14px;
      color: #666;
      float: left;
      margin: 0 10px;
      border-radius: 6px;
      transition: all 0.3s;
      cursor: pointer;
      &:hover {
        background: #efefef;
      }
      span {
        display: block;
        font-size: 40px;
        margin-bottom: 8px;
        color: #999;
      }
      p {
        display: block;
        margin: 0;
        font-size: 12px;
      }
    }
  }
}
.main {
  width: 400px;
  max-width: 400px;
  background: #fff;
  margin-top: 40px;
  position: relative;
  .top-nav {
    position: absolute;
    top: 0;
    background: #fff;
    z-index: 999;
    transition: all 0.3s;
    & * {
      pointer-events: none;
    }
    &:hover {
      transform: scale(0.95);
      border-radius: 10px;
      overflow: hidden;
      box-shadow: 0 0 10px #afafaf;
    }
    .tit {
      position: absolute;
      left: 50%;
      bottom: 10px;
      transform: translateX(-50%);
    }
    img {
      max-width: 100%;
      image-rendering: -moz-crisp-edges;
      image-rendering: -o-crisp-edges;
      image-rendering: -webkit-optimize-contrast;
      image-rendering: crisp-edges;
      -ms-interpolation-mode: nearest-neighbor;
    }
  }
  .view-content {
    width: 400px;
    height: 700px;
    background: #f5f5f5;
    overflow-y: auto;
    overflow-x: hidden;
    padding-top: 72px;
    box-shadow: 0 2px 6px #ccc;
    &::-webkit-scrollbar {
      width: 6px;
    }
    &::-webkit-scrollbar-thumb {
      background: #dbdbdb;
    }
    &::-webkit-scrollbar-track {
      background: #f6f6f6;
    }

    .item {
      transition: all 0.3s;
      background: #fff;
      &:hover {
        transform: scale(0.95);
        border-radius: 10px;
        box-shadow: 0 0 10px #afafaf;
        .el-icon-error {
          display: block;
        }
      }
      div {
        pointer-events: none;
      }
      .wait {
        background: #deedff;
        height: 35px;
        text-align: center;
        line-height: 35px;
        font-size: 12px;
        color: #666;
      }
      .el-icon-error {
        position: absolute;
        right: -10px;
        top: -6px;
        color: red;
        font-size: 25px;
        cursor: pointer;
        display: none;
        z-index: 9999;
      }
    }
  }
}

.chosen {
  border: solid 2px #3089dc !important;
}
</style>
